﻿Random random = new Random();
PasswordGenerator pwd = new PasswordGenerator(random);
for (int i = 0; i < 3; i++)
{
    pwd.Generate(4, 10, true);
}

Console.ReadKey();

public class PasswordGenerator
{
    private readonly Random _random;

    public PasswordGenerator(Random random)
    {
        _random = random;
    }

    public string Generate(int minLength, int maxLength, bool shallUseSpecial)
    {
        Validate(minLength, maxLength);

        // randomly pick the length of password between left and right range
        var passwordLength = GeneratePasswordLength(minLength, maxLength);


        var charactersToBeIncluded = shallUseSpecial
            ? "QWERTYUIOPASDFGHJKLZXCVBNM1234567890!@#$%^&*()_+[]"
            : "QWERTYUIOPASDFGHJKLZXCVBNM1234567890";

        return GenerateRandomString(passwordLength, charactersToBeIncluded);
    }

    private void Validate(int minLength, int maxLength)
    {
        // Validate max and min length
        if (minLength < 1)
        {
            throw new ArgumentOutOfRangeException(
                $"{nameof(minLength)} must be greater than 0");
        }

        if (minLength < maxLength)
        {
            throw new ArgumentOutOfRangeException(
                $"{nameof(minLength)} must be smaller than {nameof(maxLength)}");
        }
    }

    private int GeneratePasswordLength(int minLenght, int maxLength)
    {
        return _random.Next(minLenght, maxLength + 1);
    }

    private string GenerateRandomString(int length, string charactersToBeIncluded)
    {
        var passwordCharacters = Enumerable.Repeat(charactersToBeIncluded, length)
            .Select(characters => characters[_random.Next(characters.Length)])
            .ToArray();

        return new string(passwordCharacters);
    }
}